#file:c:\Users\Zhou\Desktop\training-mall-management-end\src\components\admin\ProductsView.vue
<template>
    <div class="products-view">
        <h2>商品列表</h2>
        <!-- 添加搜索框和按钮 -->
        <div class="search-bar">
            <input v-model="searchTitle" type="text" placeholder="输入商品标题查询" />
            <el-button type="primary" @click="searchProductByTitle">查询</el-button>
            <el-button type="success" @click="dialogVisible = true">添加商品</el-button>
            <!-- <el-button type="warning" @click="categoryDialogVisible = true">添加分类</el-button> -->
        </div>
        <div class="filter-bar">
            <el-select v-model="selectedCategory" placeholder="选择分类" @change="filterProductsByCategory" clearable>
                <el-option v-for="category in categories" :key="category.categoryid" :label="category.categoryname"
                    :value="category.categoryid" />
            </el-select>

        </div>
        <div v-if="loading">加载中...</div>
        <div v-else-if="error">{{ error }}</div>
        <div v-else class="product-list">
            <!-- 商品列表 -->
            <div v-if="filteredProducts.length > 0">
                <h3>商品列表</h3>
                <div class="product-grid">
                    <router-link v-for="product in filteredProducts" :key="product.productid"
                        :to="{ name: 'productDetailById', params: { productid: product.productid } }"
                        class="product-item-link">
                        <div class="product-item">
                            <img :src="product.productimg" alt="Product Image" class="product-image" />
                            <h3>{{ product.title }}</h3>
                            <p>{{ product.description }}</p>
                            <span class="product-price">{{ product.price }} 元</span>
                            <span class="product-stock">库存: {{ product.stock }}</span>
                            <span class="product-category">类别: {{ product.categoryname }}</span>
                            <span class="product-status" :class="{ onsale: product.onsale, offsale: !product.onsale }">
                                {{ product.onsale ? '上架商品' : '下架商品' }}
                            </span>
                        </div>
                    </router-link>
                </div>
            </div>
            <div v-else>
                <p>没有找到相关商品</p>
            </div>
        </div>

        <!-- 添加商品对话框 -->
        <el-dialog title="添加商品" v-model="dialogVisible" width="50%">
            <el-form :model="newProduct" label-width="100px">
                <el-form-item label="标题">
                    <el-input v-model="newProduct.title" required></el-input>
                </el-form-item>
                <el-form-item label="描述">
                    <el-input type="textarea" v-model="newProduct.description" required></el-input>
                </el-form-item>
                <el-form-item label="价格">
                    <el-input-number v-model="newProduct.price" :min="0" :precision="2" required></el-input-number>
                </el-form-item>
                <el-form-item label="库存">
                    <el-input-number v-model="newProduct.stock" :min="0" required></el-input-number>
                </el-form-item>
                <el-form-item label="类别">
                    <el-select v-model="newProduct.categoryid" placeholder="选择类别" clearable>
                        <el-option v-for="category in categories" :key="category.categoryid" :label="category.categoryname"
                            :value="category.categoryid" />
                    </el-select>
                </el-form-item>
                <el-form-item label="商品图片">
                    <el-upload class="upload-demo" action="" :on-change="handleProductImageUpload" :auto-upload="false"
                        :show-file-list="false" accept="image/*">
                        <el-button type="primary">点击上传商品图片</el-button>
                        <template #tip>
                            <div class="el-upload__tip">只能上传jpg/png文件，且不超过500kb</div>
                        </template>
                    </el-upload>
                    <div v-if="newProduct.productimg">
                        <img :src="newProduct.productimg" alt="Uploaded Product Image" class="uploaded-image" />
                    </div>
                </el-form-item>
                <el-form-item label="广告图片">
                    <el-upload class="upload-demo" action="" :on-change="handleAdImageUpload" :auto-upload="false"
                        :show-file-list="false" accept="image/*">
                        <el-button type="primary">点击上传广告图片</el-button>
                        <template #tip>
                            <div class="el-upload__tip">只能上传jpg/png文件，且不超过500kb</div>
                        </template>
                    </el-upload>
                    <div v-if="newProduct.adimg">
                        <img :src="newProduct.adimg" alt="Uploaded Ad Image" class="uploaded-image" />
                    </div>
                </el-form-item>
                <el-form-item label="上架状态">
                    <el-switch v-model="newProduct.onsale" active-text="启用" inactive-text="停用"></el-switch>
                </el-form-item>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="dialogVisible = false">取 消</el-button>
                    <el-button type="primary" @click="handleAddProduct">确 定</el-button>
                </span>
            </template>
        </el-dialog>

        <!-- 添加分类对话框 -->
        <el-dialog title="添加分类" v-model="categoryDialogVisible" width="30%">
            <el-form :model="newCategory" label-width="100px">
                <el-form-item label="分类名称">
                    <el-input v-model="newCategory.categoryname" required></el-input>
                </el-form-item>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="categoryDialogVisible = false">取 消</el-button>
                    <el-button type="primary" @click="handleAddCategory">确 定</el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>

<script setup>
import { ref, onMounted, computed } from 'vue';
import { useRouter } from 'vue-router';
import { getAllProduct, getProductByTitle, addProduct1, addProductimg, addAdimg } from '../../api/product.js';
import { getAllCategories, addCategory } from '../../api/category.js';

const router = useRouter();
const products = ref([]);
const loading = ref(false);
const error = ref(null);
const searchTitle = ref('');
const dialogVisible = ref(false);
const categoryDialogVisible = ref(false);
const newProduct = ref({
    title: '',
    description: '',
    price: 0.0,
    stock: 0,
    categoryid: null,
    productimg: null,
    adimg: null,
    onsale: false,
    categoryname: ''
});
const productImageFile = ref(null);
const adImageFile = ref(null);
const categories = ref([]);
const selectedCategory = ref('');
const newCategory = ref({
    categoryname: ''
});

// 计算属性：过滤后的商品列表
const filteredProducts = computed(() => {
    if (selectedCategory.value) {
        return products.value.filter(product => product.categoryid === selectedCategory.value);
    }
    return products.value;
});

// 获取所有分类
const fetchCategories = async () => {
    try {
        const response = await getAllCategories();
        console.log('[DEBUG] 完整响应对象:', response);
        if (response?.data?.code === 1) { // 严格校验数据结构
            categories.value = response.data.data;
            console.log('查询出的全部分类数据:', response.data.data);
        } else {
            console.error('异常响应结构:', response?.data);
            error.value = response?.data?.msg || '数据格式错误';
        }
    } catch (err) {
        console.error('请求捕获异常:', err.message, '完整错误:', err);
        error.value = `网络错误: ${err.message}`;
    }
};

// 修改后的请求逻辑（增加错误详情输出）
onMounted(async () => {
    loading.value = true;
    try {
        const response = await getAllProduct();
        console.log('[DEBUG] 完整响应对象:', response);
        if (response?.data?.code === 1) { // 严格校验数据结构
            products.value = response.data.data;
            console.log('查询出的全部商品数据:', response.data.data);
        } else {
            console.error('异常响应结构:', response?.data);
            error.value = response?.data?.msg || '数据格式错误';
        }
    } catch (err) {
        console.error('请求捕获异常:', err.message, '完整错误:', err);
        error.value = `网络错误: ${err.message}`;
    } finally {
        loading.value = false;
    }
    fetchCategories(); // 获取所有分类
});

// 新增方法：根据商品标题查询
const searchProductByTitle = async () => {
    if (!searchTitle.value) {
        error.value = '请输入商品标题';
        return;
    }
    loading.value = true;
    try {
        const response = await getProductByTitle(searchTitle.value);
        console.log('[DEBUG] 根据标题查询响应对象:', response);
        if (response?.data?.code === 1) { // 严格校验数据结构
            products.value = response.data.data;
            console.log('根据标题查询出的商品数据:', response.data.data);
        } else {
            console.error('异常响应结构:', response?.data);
            error.value = response?.data?.msg || '数据格式错误';
        }
    } catch (err) {
        console.error('请求捕获异常:', err.message, '完整错误:', err);
        error.value = `网络错误: ${err.message}`;
    } finally {
        loading.value = false;
    }
};

// 处理商品图片上传
const handleProductImageUpload = (file) => {
    productImageFile.value = file.raw;
    newProduct.value.productimg = URL.createObjectURL(file.raw);
};

// 处理广告图片上传
const handleAdImageUpload = (file) => {
    adImageFile.value = file.raw;
    newProduct.value.adimg = URL.createObjectURL(file.raw);
};
//添加商品
// 添加商品
const handleAddProduct = async () => {
    try {
        // 第一步：添加商品的基本信息
        const response = await addProduct1({
            title: newProduct.value.title,
            description: newProduct.value.description || '',
            price: newProduct.value.price,
            stock: newProduct.value.stock,
            categoryid: newProduct.value.categoryid,
            onsale: newProduct.value.onsale
        });

        if (response.data.code !== 1) {
            throw new Error(response.data.msg || '添加商品基本信息失败');
        }
        console.log('添加商品基本信息成功:', response.data);

        const productid = parseInt(response.data.data);
        console.log('拿到商品id成功:', response.data.data);

        // 第二步：添加商品图片
        if (!(productImageFile.value instanceof File)) {
            throw new Error('请选择商品主图');
        }

        const productImgResponse = await addProductimg(productid, productImageFile.value);
        if (productImgResponse.data.code !== 1) {
            throw new Error(productImgResponse.data.msg || '上传商品图片失败');
        }

        // 第三步：添加广告图片（如果存在）
        if (adImageFile.value instanceof File) {
            const adImgResponse = await addAdimg(productid, adImageFile.value);
            if (adImgResponse.data.code !== 1) {
                throw new Error(adImgResponse.data.msg || '上传广告图片失败');
            }
        }

        // 成功处理
        console.log('商品添加成功:', response.data);
        dialogVisible.value = false;
        fetchProducts(); // 刷新商品列表
        resetForm(); // 重置表单
    } catch (err) {
        console.error('添加商品时发生错误:', err.message);
        error.value = err.message;
    }
};

// 重置表单的方法
const resetForm = () => {
    newProduct.value = {
        title: '',
        description: '',
        price: 0.0,
        stock: 0,
        categoryid: null,
        productimg: null,
        adimg: null,
        onsale: false,
        categoryname: ''
    };
    productImageFile.value = null;
    adImageFile.value = null;
};
// 刷新商品列表
const fetchProducts = async () => {
    loading.value = true;
    try {
        const response = await getAllProduct();
        console.log('[DEBUG] 完整响应对象:', response);
        if (response?.data?.code === 1) { // 严格校验数据结构
            products.value = response.data.data;
            console.log('查询出的全部商品数据:', response.data.data);
        } else {
            console.error('异常响应结构:', response?.data);
            error.value = response?.data?.msg || '数据格式错误';
        }
    } catch (err) {
        console.error('请求捕获异常:', err.message, '完整错误:', err);
        error.value = `网络错误: ${err.message}`;
    } finally {
        loading.value = false;
    }
};

// 根据分类过滤商品
const filterProductsByCategory = () => {
    console.log('选择的分类ID:', selectedCategory.value);
};

// 添加分类
const handleAddCategory = async () => {
    if (!newCategory.value.categoryname || newCategory.value.categoryname.trim() === '') {
        error.value = '请输入有效的分类名称';
        return;
    }
    console.log("实际发送值:", JSON.stringify({ categoryname: newCategory.value.categoryname}))
    try {
        const response = await addCategory({
            categoryname: newCategory.value.categoryname
        });

        console.log('[添加分类] 完整响应对象:', response);
        console.log('添加的分类为：', newCategory.value.categoryname);
        if (response.data.code === 1) {
            console.log('分类添加成功:', response.data.msg);
            fetchCategories(); // 刷新分类列表
            newCategory.value.categoryname = '';
            categoryDialogVisible.value = false;
        } else {
            console.error('分类添加失败:', response.data.msg);
            error.value = response.data.msg;
        }
    } catch (err) {
        console.error('请求捕获异常:', err.message, '完整错误:', err);
        error.value = `网络错误: ${err.message}`;
    }
};
</script>

<style scoped>
.products-view {
    padding: var(--padding-base);
    background-color: var(--background-color);
}

.search-bar {
    margin-bottom: 1rem;
    display: flex;
    align-items: center;
}

.search-bar input {
    padding: 0.5rem;
    width: 70%;
    margin-right: 0.5rem;
}

.search-bar button {
    padding: 0.5rem 1rem;
    background-color: var(--primary-color);
    color: white;
    border: none;
    border-radius: var(--border-radius);
    cursor: pointer;
}

.search-bar button:hover {
    background-color: darken(var(--primary-color), 10%);
}

.filter-bar {
    margin-bottom: 1rem;
    display: flex;
    align-items: center;
}

.filter-bar .el-select {
    width: 70%;
    margin-right: 0.5rem;
}

.filter-bar .el-button {
    padding: 0.5rem 1rem;
    background-color: var(--warning-color);
    color: white;
    border: none;
    border-radius: var(--border-radius);
    cursor: pointer;
}

.filter-bar .el-button:hover {
    background-color: darken(var(--warning-color), 10%);
}

.product-list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.product-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 1rem;
}

.product-item-link {
    text-decoration: none;
    color: inherit;
}

.product-item {
    background-color: #f9fafb;
    border: 1px solid #ebebeb;
    border-radius: var(--border-radius);
    padding: 0.75rem;
    /* 减小内边距 */
    text-align: center;
    transition: box-shadow 0.3s ease;
    cursor: pointer;
}

.product-item:hover {
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.product-image {
    max-width: 100%;
    height: auto;
    border-radius: var(--border-radius);
}

.product-price {
    color: var(--primary-color);
    font-weight: bold;
}

.product-stock {
    color: #666;
    font-size: 0.8rem;
    /* 减小字体大小 */
}

.product-category {
    color: #333;
    font-size: 0.8rem;
    /* 减小字体大小 */
}

/* 添加商品状态样式 */
.product-status {
    font-size: 0.8rem;
    /* 减小字体大小 */
    margin-top: 0.5rem;
    display: block;
}

.product-status.onsale {
    color: green;
}

.product-status.offsale {
    color: red;
}

.uploaded-image {
    max-width: 100px;
    margin-top: 10px;
}
</style>